#include <QtGui>
#include <QtXml>


#include "attributesmodel.h"
#include "attribute.h"

AttributesModel::AttributesModel(QObject *parent)
    : QAbstractListModel(parent)
{
    Attribute::num=1;
//	_selected = 0;
}
//
//
//
AttributesModel::~AttributesModel()
{
	clear();	
}
//
QVariant AttributesModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    switch(role){
		case Qt::DisplayRole:
			return QVariant(_attributes.value(index.row())->alias());
		case Qt::FontRole:
			return QVariant(_attributes.value(index.row())->font());
		case Qt::TextColorRole:
			return QVariant(_attributes.value(index.row())->color());
		case Qt::UserRole:
			return qVariantFromValue((QObject*)_attributes.value(index.row()));
		
	}

    return QVariant();
}
//
int AttributesModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    else
        return _attributes.size();
}
//
void AttributesModel::addAttribute(QMap<QString,QString> params)
{
	QMap<QString,QString> *param = new QMap<QString,QString>(params);
	QString alias,name,type,szOrder;
	int order;
	alias = (*param)["alias"];
	name  = (*param)["name"];
	type  = (*param)["type"];
	szOrder = (*param)["number"];
	if(type=="") type="string";
	bool ok=false;
	order = szOrder.toInt(&ok);
	if(!ok) order = 0;
    Attribute *wordLabel = new Attribute(alias, 0,name,type,order);
    // установка параметров для домена
    wordLabel->setLength(QString((*param)["length"]).toInt());
    wordLabel->setIdConf(QString((*param)["idconf"]).toInt());
    wordLabel->setOpened(QString((*param)["opened"]).toInt());
	int row = _attributes.size();
	beginInsertRows(QModelIndex(), row, row);
	_attributes.push_back(wordLabel);
	endInsertRows();
    connect(wordLabel,SIGNAL(attrChanged(int,Attribute*)),this,SIGNAL(attrChanged(int,Attribute*)));	
	delete param;
}
//
bool AttributesModel::addAttribute(QDomNode &node)
{
	QMap<QString,QString> params;
	// загрузка данных из ветви xml
	QString alias,name,type,order,x="0",y="0";
	QDomElement elem;
	name = node.toElement().attribute("name","");

	elem = node.firstChildElement("id"); 	// alias
	if(elem.isNull()) return false;
	alias = elem.text();
	elem = node.firstChildElement("type");
	if(elem.isNull()) return false;	
	type = elem.text();
	elem = node.firstChildElement("order");		
	if(elem.isNull()) return false;
	order = elem.text();
// длина атрибута
	elem = node.firstChildElement("length");		
	if(!elem.isNull()) 
		params["length"] = elem.text();
// режим присвоения идентификационных номеров
	elem = node.firstChildElement("idconf");		
	if(!elem.isNull()) 
		params["idconf"] = elem.text();

	elem = node.firstChildElement("opened");		
	if(!elem.isNull()) 
		params["opened"] = elem.text();

	params["alias"] = alias;
	params["name"]  = name;
	params["type"]  = type;
	params["order"] = order;

	addAttribute(params);
	// установка текущего порядка 
	if(order.toInt()>Attribute::num) Attribute::num = order.toInt()+1;
//	DragLabel *wordLabel = new DragLabel(alias,this,name,type,order);
	return true;
}
//
void AttributesModel::xml(QDomNode &node)
{ // xml код доменов
	foreach(Attribute *attr,_attributes){
		attr->xml(node);
	}
}
// возвращает домен по его порядковому номеру
Attribute *AttributesModel::attribute(int order)
{
 	for (int i = 0; i < _attributes.size(); ++i) 
	     if (_attributes.at(i)->order() == order)
	     	return _attributes.at(i);	     	

	return 0;
}
//
int AttributesModel::newNumber()
{
 	int newnumber = 0;
	for (int i = 0; i < _attributes.size(); ++i) 
	     if (_attributes.at(i)->order() > newnumber)
	     	newnumber = _attributes.at(i)->order();
	return newnumber+1;
}
//
void AttributesModel::editAttribute(QModelIndex &index)
{
	if(index.isValid())
		_attributes.value(index.row())->slotEdit();
//	if(_selected){
//		_selected->slotEdit();
//	}
}
//
void AttributesModel::removeAttributes(QModelIndexList ilist)
{
	if(!ilist.size()) return;
    int row   = ilist.first().row();
    int count = ilist.count();
	removeRows(row,count);
    /*int beginRow = qMax(0, row);
    int endRow = qMin(row + count - 1, _attributes.size() - 1);
	QModelIndex parent;
    beginRemoveRows(parent, beginRow, endRow);

    while (beginRow <= endRow) {
        _attributes.removeAt(beginRow);
        ++beginRow;
    }

    endRemoveRows();		*/

}

bool AttributesModel::removeRows(int row,int count,const QModelIndex &parent)
{
	qDebug() << Q_FUNC_INFO << row << count;
    int beginRow = qMax(0, row);
    int endRow = qMin(row + count - 1, _attributes.size() - 1);
    beginRemoveRows(parent, beginRow, endRow);
    while (beginRow <= endRow) {
        _attributes.removeAt(beginRow);
        ++beginRow;
    }
    endRemoveRows();		

	return true;
}
//
Qt::ItemFlags AttributesModel::flags(const QModelIndex &index) const
{
    if (index.isValid()) {
        return ( Qt::ItemIsEnabled | Qt::ItemIsSelectable
              | Qt::ItemIsDragEnabled );
    }

    return Qt::ItemIsDropEnabled;
}
//
Qt::DropActions AttributesModel::supportedDropActions() const
{
    return Qt::CopyAction | Qt::MoveAction;
}
//
QStringList AttributesModel::mimeTypes() const
{
    QStringList types;
    types << "application/x-attribute";
    return types;
}
//
QMimeData *AttributesModel::mimeData(const QModelIndexList &indexes) const
{
    QMimeData *mimeData = new QMimeData();
    QByteArray encodedData;

    QDataStream stream(&encodedData, QIODevice::WriteOnly);

    foreach (QModelIndex index, indexes) {
        if (index.isValid()) {
            Attribute *attribute = _attributes.value(index.row()); 
            stream << attribute->order();
        }
    }

    mimeData->setData("application/x-attribute", encodedData);
    return mimeData;
}
//
//
//
void AttributesModel::moveAttribute(int nom,QModelIndex &index)
{
	// change attribute position
	int i=0;
	foreach(Attribute *attr,_attributes){
		if(attr->order()==nom) break;
		i++;
	}
	if( i >= _attributes.size()) return;
	// remove attribute  from current position
	beginRemoveRows(QModelIndex(),i,i);
	Attribute *attr = _attributes.takeAt(i);
	endRemoveRows();
	// insert attribute to new position
	beginInsertRows(QModelIndex(),index.row(),index.row());
	_attributes.insert(index.row(),attr);
	endInsertRows();
	updateAttributesOrder();
}
//
void AttributesModel::updateAttributesOrder()
{
	int i=0;
	foreach(Attribute *attr,_attributes){
		attr->setOrder(++i);
	}
}
//
bool AttributesModel::checkUsed(QTreeWidgetItem *item,int order)
{
	if(item->data(0,Qt::UserRole) == order) return true;
	for(int i=0;i<item->childCount();i++)
		if(checkUsed(item->child(i),order)) return true;
	return false;
}
//
void AttributesModel::checkUsed(QTreeWidget *tree)
{
	//qDebug("checkUsed tree");
	bool used = false;
	foreach(Attribute *attr,_attributes){
		used = false;
		for(int i = 0; i < tree->topLevelItemCount(); i++)
			if(checkUsed(tree->topLevelItem(i),attr->order())){
				used = true;
   			    break;	
			}
		attr->setUsed(used);
	}
}
//
void AttributesModel::clear()
{
	beginRemoveRows(QModelIndex(),0,_attributes.count());
	qDeleteAll(_attributes);
	_attributes.clear();
	endRemoveRows();	
}

/*! возвращает новое имя для координаты
*/
QString AttributesModel::newName()
{
	return QString("coordinate%1").arg(_attributes.count()+1);
}

Attribute *AttributesModel::attrFromIndex(const QModelIndex &index)
{
	if(!index.isValid()) return 0;
	return	_attributes.value(index.row());
}
